/*
 * Copyright (c) laokz <laokz@foxmail.com>
 * VMWIFI is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#ifndef __VMWIFI_H__
#define __VMWIFI_H__

#include <netlink/handlers.h>

/*
 * VMWIFI and guest interact all by special type ethernet packets. The
 * type is chosen from IEEE802 undefined numbers, that we have chance to
 * communicate with no need to enable virtual bridge promiscuous mode.
 */
#define VW_ETHER_FRAME_TYPE     0xFACE

/*
 * Represent request/response code.
 * Putting in the beginning of ethernet frame payload, occupy 2 bytes.
 *
 * Following the code is request parameters or response information if any.
 *
 * Note: All these data are host byte order.
 */
enum VwCodeT {
    VW_CODE_INVALID,    /* invalid, might ignore and retry */
    VW_CODE_SCAN_ALL,   /* scan, without any parameters */

    VW_CODE_DONE,       /* only for response, inform guest response is over */
    VW_CODE_NUMS = VW_CODE_DONE,
};

/*
 * Init VMWIFI environment.
 *
 * `iface` is a virtual bridge name guest linked to. If NULL, default to 'br0'.
 *
 * return 0 - success, -1 if failure
 *
 * Note: All APIs are fragile. When error occurred, then should stop to run.
 *       Reasons are output to `stderr` or can be redirected to a log file.
 */
int VwInit(const char *iface);

#define VW_BRIDGE_NAME_DFT      "br0"

void VwDeInit(void);

/*
 * Wait for guest request, return `VwCodeT` enum or -1 if failed.
 *
 * Note: VMWIFI use single thread model. Only one request served,
 *       then can the other one. It doesn't use any lock.
 */
int VwWaitRequest(void);

/*
 * Trigger host wlan scan, collect result, then send back to guest.
 *
 * `f` will be called when nl80211 feedback NL80211_CMD_GET_SCAN results.
 * `arg` is its argument. Refer to <linux/nl80211.h>.
 *
 * return 0 - success, -1 if failure
 *
 * Note: When all responses to the request are finished, it will auto send
 * `VW_CODE_DONE` to guest.
 */
int VwDoScan(nl_recvmsg_msg_cb_t f, void *arg);

/*
 * Send `data` of `len` size to guest. `srcMac` represent source interface
 * MAC, might be NULL.
 *
 * Note: The data will be set as ethernet frame payload. It's size should
 *       not exceed 1500 bytes, and the first 2 bytes must be `VwCodeT`.
 */
void VwSendResponse(const char srcMac[], const char *data, int len);

#endif
